bitkeeper revision 1.1159.51.1 (412cb2756vYHD-1PDPrd90VZuLl1EQ)
authorkaf24@labyrinth.cl.cam.ac.uk <kaf24@labyrinth.cl.cam.ac.uk>
Wed, 25 Aug 2004 15:38:29 +0000 (15:38 +0000)
committerkaf24@labyrinth.cl.cam.ac.uk <kaf24@labyrinth.cl.cam.ac.uk>
Wed, 25 Aug 2004 15:38:29 +0000 (15:38 +0000)
Fix netif and blkif interface deferred disconnection. It must occur in
a process context because we call vfree().

linux-2.4.27-xen-sparse/include/asm-xen/queues.h
linux-2.6.7-xen-sparse/drivers/xen/blkback/common.h
linux-2.6.7-xen-sparse/drivers/xen/blkback/interface.c
linux-2.6.7-xen-sparse/drivers/xen/netback/common.h
linux-2.6.7-xen-sparse/drivers/xen/netback/interface.c

index 95bddf38876dcf2e9f71188762afaa32d8330d13..dd527603ceb568d0d6d397975fbfe61c4ea7d51d 100644 (file)
 
 #define DECLARE_TQUEUE(_name, _fn, _arg) \
     struct tq_struct _name = { LIST_HEAD_INIT((_name).list), 0, _fn, _arg }
-
 #define DECLARE_WORK(_name, _fn, _arg) DECLARE_TQUEUE(_name, _fn, _arg)
+
+#define work_struct tq_struct
+#define INIT_WORK(_work, _fn, _arg) INIT_TQUEUE(_work, _fn, _arg)
+
 #define schedule_work(_w) schedule_task(_w)
 
 #endif /* __QUEUES_H__ */
index 0d1fbc2e4ed4f3297c8813b2e2a41aaf1fa8653d..0fa60cdceb827cc31fd0af710d2ff6a5fb0594e1 100644 (file)
@@ -60,19 +60,21 @@ typedef struct blkif_st {
     struct list_head blkdev_list;
     spinlock_t       blk_ring_lock;
     atomic_t         refcnt;
+
+    struct work_struct work;
 } blkif_t;
 
 void blkif_create(blkif_be_create_t *create);
 void blkif_destroy(blkif_be_destroy_t *destroy);
 void blkif_connect(blkif_be_connect_t *connect);
 int  blkif_disconnect(blkif_be_disconnect_t *disconnect, u8 rsp_id);
-void __blkif_disconnect_complete(blkif_t *blkif);
+void blkif_disconnect_complete(blkif_t *blkif);
 blkif_t *blkif_find_by_handle(domid_t domid, unsigned int handle);
 #define blkif_get(_b) (atomic_inc(&(_b)->refcnt))
 #define blkif_put(_b)                             \
     do {                                          \
         if ( atomic_dec_and_test(&(_b)->refcnt) ) \
-            __blkif_disconnect_complete(_b);      \
+            blkif_disconnect_complete(_b);        \
     } while (0)
 
 /* An entry in a list of xen_extents. */
index 3cd76b7120a98428dee378fe42db42566b1deba9..4196014597fb4d56c0f14e086988b955144a4f2b 100644 (file)
@@ -27,13 +27,14 @@ blkif_t *blkif_find_by_handle(domid_t domid, unsigned int handle)
     return blkif;
 }
 
-void __blkif_disconnect_complete(blkif_t *blkif)
+static void __blkif_disconnect_complete(void *arg)
 {
+    blkif_t              *blkif = (blkif_t *)arg;
     ctrl_msg_t            cmsg;
     blkif_be_disconnect_t disc;
 
     /*
-     * These can't be done in __blkif_disconnect() because at that point there
+     * These can't be done in blkif_disconnect() because at that point there
      * may be outstanding requests at the disc whose asynchronous responses
      * must still be notified to the remote driver.
      */
@@ -67,6 +68,12 @@ void __blkif_disconnect_complete(blkif_t *blkif)
     ctrl_if_send_response(&cmsg);
 }
 
+void blkif_disconnect_complete(blkif_t *blkif)
+{
+    INIT_WORK(&blkif->work, __blkif_disconnect_complete, (void *)blkif);
+    schedule_work(&blkif->work);
+}
+
 void blkif_create(blkif_be_create_t *create)
 {
     domid_t       domid  = create->domid;
index 6910c6116521b3cf570c251b3f601106c8df3090..6646f5339f17b513c89c0e0f82b5fa49e16861a9 100644 (file)
@@ -70,19 +70,21 @@ typedef struct netif_st {
     spinlock_t       rx_lock, tx_lock;
     struct net_device *dev;
     struct net_device_stats stats;
+
+    struct work_struct work;
 } netif_t;
 
 void netif_create(netif_be_create_t *create);
 void netif_destroy(netif_be_destroy_t *destroy);
 void netif_connect(netif_be_connect_t *connect);
 int  netif_disconnect(netif_be_disconnect_t *disconnect, u8 rsp_id);
-void __netif_disconnect_complete(netif_t *netif);
+void netif_disconnect_complete(netif_t *netif);
 netif_t *netif_find_by_handle(domid_t domid, unsigned int handle);
 #define netif_get(_b) (atomic_inc(&(_b)->refcnt))
 #define netif_put(_b)                             \
     do {                                          \
         if ( atomic_dec_and_test(&(_b)->refcnt) ) \
-            __netif_disconnect_complete(_b);      \
+            netif_disconnect_complete(_b);        \
     } while (0)
 
 void netif_interface_init(void);
index 76d23171b24140f2476d37b764433bd9be84e276..406d253fdae6294c0d7e760eab62a438740bf623 100644 (file)
@@ -27,13 +27,14 @@ netif_t *netif_find_by_handle(domid_t domid, unsigned int handle)
     return netif;
 }
 
-void __netif_disconnect_complete(netif_t *netif)
+static void __netif_disconnect_complete(void *arg)
 {
+    netif_t              *netif = (netif_t *)arg;
     ctrl_msg_t            cmsg;
     netif_be_disconnect_t disc;
 
     /*
-     * These can't be done in __netif_disconnect() because at that point there
+     * These can't be done in netif_disconnect() because at that point there
      * may be outstanding requests at the disc whose asynchronous responses
      * must still be notified to the remote driver.
      */
@@ -70,6 +71,12 @@ void __netif_disconnect_complete(netif_t *netif)
     ctrl_if_send_response(&cmsg);
 }
 
+void netif_disconnect_complete(netif_t *netif)
+{
+    INIT_WORK(&netif->work, __netif_disconnect_complete, (void *)netif);
+    schedule_work(&netif->work);
+}
+
 void netif_create(netif_be_create_t *create)
 {
     int                err = 0;